package com.chatplus.application.web.advice;

import com.chatplus.application.common.domain.response.PayloadOnlyResponse;
import com.chatplus.application.common.domain.response.TurnRightResponse;
import com.chatplus.application.json.JsonWriter;
import com.chatplus.application.web.interceptor.AuditLoggerInterceptor;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;

@SuppressWarnings("NullableProblems")
@RestControllerAdvice(basePackages = {"com.chatplus", "test"})
@Order
public class TurnRightResponseAdvice implements ResponseBodyAdvice<Object> {
    private final static SouthernQuietLogger log = SouthernQuietLoggerFactory.getLogger(TurnRightResponseAdvice.class);

    private final JsonWriter jsonWriter;

    public TurnRightResponseAdvice(JsonWriter jsonWriter) {
        this.jsonWriter = jsonWriter;
    }

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        // 审计日志相关--开始
        ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
        HttpServletRequest req = servletServerHttpRequest.getServletRequest();
        handleEmptyList(body);
        req.setAttribute(AuditLoggerInterceptor.AUDIT_LOGGER_BODY, body);
        // 审计日志相关--结束

        if (!selectedContentType.includes(MediaType.APPLICATION_JSON)) {
            return body;
        }
        if (selectedContentType.toString().contains("actuator")) {
            return body;
        }
        if (body instanceof TurnRightResponse) {

            log.message("业务逻辑直接生成了TurnRightResponse")
                .context("body", body)
                .debug();

            return body;
        }

        if (body instanceof PayloadOnlyResponse) {
            return ((PayloadOnlyResponse) body).getPayload();
        }

        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);

        try (OutputStream outputStream = response.getBody()) {
            jsonWriter.write(outputStream, new TurnRightResponse("", body));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return null;
    }
    private void handleEmptyList(Object object) {
        try {
            if (object != null) {
                if (object instanceof List) {
                    List objectList = (List) object;
                    for (Object o : objectList) {
                        handleEmptyList(o);
                    }
                } else {
                    // 拿到该类
                    Class<?> clz = object.getClass();
                    // 获取实体类的所有属性，返回Field数组
                    Field[] fields = clz.getDeclaredFields();
                    for (Field field : fields) {
                        if (field.getGenericType().toString().contains("java.util.List")) {
                            field.setAccessible(true);
                            if (field.get(object) == null) {
                                field.set(object, Collections.emptyList());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.message("为Null的List转化为空失败").exception(e).error();
        }
    }
}
